home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src / ace / c / declare.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  19.3 KB  |  857 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: variable, structure, constant and external object 
  6.    ** declaration/definition code **
  7.    ** Copyright (C) 1998 David Benn
  8.    ** 
  9.    ** This program is free software; you can redistribute it and/or
  10.    ** modify it under the terms of the GNU General Public License
  11.    ** as published by the Free Software Foundation; either version 2
  12.    ** of the License, or (at your option) any later version.
  13.    **
  14.    ** This program is distributed in the hope that it will be useful,
  15.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.    ** GNU General Public License for more details.
  18.    **
  19.    ** You should have received a copy of the GNU General Public License
  20.    ** along with this program; if not, write to the Free Software
  21.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  22.  
  23.    Author: David J Benn
  24.      Date: 26th October-30th November, 1st-13th December 1991,
  25.        14th,20th-27th January 1992, 
  26.            2nd-17th, 21st-29th February 1992, 
  27.        1st,13th,14th,22nd,23rd March 1992,
  28.        21st,22nd April 1992,
  29.        2nd,3rd,11th,15th,16th May 1992,
  30.        7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
  31.        2nd-8th,14th-19th,26th-29th July 1992,
  32.        1st-3rd,7th,8th,9th August 1992,
  33.        6th,7th December 1992,
  34.        14th February 1993,
  35.        12th,16th April 1993,
  36.        20th,30th June 1993,
  37.        15th December 1993,
  38.        2nd January 1994,
  39.        26th February 1994,
  40.        12th June 1994,
  41.        8th,9th September 1994,
  42.        1st,2nd October 1994,
  43.        11th,22nd June 1996
  44. */
  45.  
  46. #include "acedef.h"
  47.  
  48. /* locals */
  49. static    char     *frame_ptr[] = { "(a4)","(a5)" };
  50.  
  51. /* externals */
  52. extern    int    sym;
  53. extern    int    typ;
  54. extern    int    lev;
  55. extern    int      structcount;
  56. extern    char       id[MAXIDSIZE]; 
  57. extern    char       ut_id[MAXIDSIZE];
  58. extern    SHORT      shortval;
  59. extern    LONG       longval; 
  60. extern    float      singleval;
  61. extern    SYM    *curr_item;
  62. extern    SYM    *structdef_item;
  63. extern    STRUCM    *curr_structmem;
  64. extern    BOOL    end_of_source;
  65.  
  66.  
  67. /* functions */
  68. void define_structure()
  69. {
  70. /* define a structure data type */
  71.  
  72. SHORT mem_count=0;
  73. SYM   *structdef_item,*struct_mbr_def;
  74. int   mem_type;
  75. int   oldlevel;
  76. LONG  string_size;
  77.  
  78. /* define all structures 
  79.    at level ZERO */
  80. oldlevel=lev;
  81. lev=ZERO;
  82.  
  83. insymbol();
  84. if (sym != ident)
  85.    _error(7);
  86. else
  87. {
  88.  if (exist(id,structdef))
  89.     _error(62);
  90.  else
  91.  {
  92.   /* create symbol table entry */
  93.   enter(id,notype,structdef,0);
  94.   structdef_item=curr_item;
  95.  
  96.   /* get structure members */
  97.   insymbol();
  98.   while (sym == endofline) insymbol();  /* skip blank line(s) */
  99.  
  100.   do
  101.   {
  102.    if ((sym != bytesym) && (sym != shortintsym) && (sym != addresssym) &&
  103.        (sym != longintsym) && (sym != singlesym) && (sym != stringsym) &&
  104.        (sym != ident))
  105.       { _error(63); insymbol(); }
  106.    else
  107.    {
  108.     struct_mbr_def = NULL;
  109.  
  110.     /* type of member? */
  111.     switch(sym)
  112.     {
  113.      case bytesym     : mem_type=bytetype; break;
  114.      case shortintsym : mem_type=shorttype; break;
  115.      case longintsym  : mem_type=longtype; break;
  116.      case addresssym  : mem_type=longtype; break;
  117.      case singlesym   : mem_type=singletype; break;
  118.      case stringsym   : mem_type=stringtype; break;    
  119.      case ident       :    mem_type=structure; 
  120.             if (!exist(id,structdef) || 
  121.                 strcmp(id,structdef_item->name) == 0)
  122.             {
  123.                 _error(65); /* unknown or current structdef */
  124.                 mem_type = undefined;
  125.             }
  126.             else
  127.                 /* structure definition */
  128.                    struct_mbr_def = curr_item;
  129.             break;
  130.     }
  131.     
  132.     if (mem_type == undefined)
  133.     insymbol();
  134.     else
  135.     {
  136.       insymbol();
  137.       if (sym != ident)
  138.       { _error(7); insymbol(); }
  139.       else
  140.       { 
  141.          add_struct_member(structdef_item,id,mem_type,struct_mbr_def); 
  142.           mem_count++; 
  143.       }
  144.     }
  145.  
  146.     insymbol();
  147.  
  148.     /* specify optional string size? */
  149.     if ((mem_type == stringtype) && (sym == sizesym))
  150.     {
  151.      insymbol();
  152.      if (sym == shortconst) string_size=(LONG)shortval;
  153.      else
  154.      if (sym == longconst) string_size=longval;
  155.      else 
  156.      if (sym == ident && exist(id,constant))
  157.      {
  158.     /* short or long defined constant? */
  159.     if (curr_item->type == shorttype)
  160.        string_size=(LONG)curr_item->numconst.shortnum;
  161.     else
  162.     if (curr_item->type == longtype)
  163.        string_size=curr_item->numconst.longnum;
  164.     else
  165.         _error(4);  /* needed a short or long constant */
  166.      }
  167.      else
  168.          _error(27); /* numeric constant expected */
  169.  
  170.      if (string_size <= 0L) _error(41);  /* non-positive string size! */
  171.  
  172.      insymbol();
  173.  
  174.      /* change member and struct info */
  175.      curr_structmem->strsize = string_size;
  176.      structdef_item->size -= MAXSTRLEN;  /* subtract default string size */
  177.      structdef_item->size += string_size; 
  178.     } 
  179.    }
  180.    while (sym == endofline) insymbol();  /* skip blank line(s) */
  181.   }
  182.   while (sym != endsym && sym != structsym && !end_of_source);
  183.     
  184.   if (sym != endsym)
  185.      _error(64);
  186.   else
  187.   {                 
  188.    insymbol();
  189.    if (sym != structsym) _error(64); else insymbol();
  190.   }
  191.     
  192.   /* don't want to free memory if no member list! */
  193.   if (mem_count == 0) structdef_item->object = undefined;
  194.  }
  195. }
  196. lev=oldlevel;  /* restore level */
  197. }
  198.  
  199. void declare_structure()
  200. {
  201. /* declare one or more instances
  202.    of a structure (at level ZERO).
  203.  
  204.    syntax: DECLARE STRUCT <struct-type> [*] <ident> [,[*] <ident>..]
  205.  
  206. */
  207. STRUCM *curr_member;
  208. BOOL   struct_pointer=FALSE;
  209. char   addrbuf[40],numbuf[40];
  210. char   structname[80],structlabel[80];
  211. char   strsize[20],bss_spec[40];
  212.  
  213.  insymbol();
  214.  
  215.  if (sym != ident)
  216.     { _error(7); insymbol(); }
  217.  else
  218.  {
  219.   if (!exist(id,structdef))
  220.      { _error(65); insymbol(); }  /* unknown structdef */
  221.   else
  222.   {
  223.    structdef_item = curr_item; /* pointer to structdef info */
  224.  
  225.    do
  226.    {
  227.     insymbol();
  228.     if (sym == multiply) { struct_pointer=TRUE; insymbol(); }
  229.  
  230.     if (sym != ident)
  231.        _error(7);
  232.     else
  233.     {
  234.      if (exist(id,structure))
  235.         _error(66);
  236.      else
  237.      {
  238.       /* enter instance of structure in
  239.          symbol table and get stack frame
  240.          address.
  241.       */
  242.       enter(id,notype,structure,0);
  243.       curr_item->other = structdef_item; /* ptr to structdef node in symtab */
  244.  
  245.       itoa(-1*curr_item->address,addrbuf,10);
  246.       strcat(addrbuf,frame_ptr[lev]);
  247.  
  248.       /* if a pointer to a structure
  249.          make it NULL otherwise create 
  250.          a BSS object.
  251.       */
  252.       if (struct_pointer)
  253.          gen("move.l","#0",addrbuf); /* pointer to structure */
  254.       else
  255.       {
  256.        /* BSS structure name */
  257.        strcpy(structname,"_structure");
  258.        itoa(structcount++,numbuf,10);
  259.        strcat(structname,numbuf); 
  260.  
  261.        /* BSS structure label */
  262.        strcpy(structlabel,structname);
  263.        strcat(structlabel,":\0");
  264.  
  265.        /* create BSS object - long word aligned! */
  266.        enter_BSS("  ","CNOP 0,4");
  267.        enter_BSS(structlabel,"  ");
  268.  
  269.        curr_member = structdef_item->structmem->next; /* head has no mbr data */
  270.        while (curr_member != NULL)
  271.        {
  272.         switch(curr_member->type)
  273.         {
  274.          case bytetype   : enter_BSS("  ","ds.b 1"); break;
  275.          case shorttype  : enter_BSS("  ","ds.w 1"); break;
  276.          case longtype   : enter_BSS("  ","ds.l 1"); break;
  277.          case singletype : enter_BSS("  ","ds.l 1"); break;
  278.  
  279.      case stringtype : 
  280.      case structure  : ltoa(curr_member->strsize,strsize,10);
  281.                strcpy(bss_spec,"ds.b ");
  282.                strcat(bss_spec,strsize);
  283.                enter_BSS("  ",bss_spec);
  284.                break; 
  285.         }
  286.         curr_member = curr_member->next;
  287.        }
  288.  
  289.        enter_BSS("  ","  ");  /* place a space before next BSS object! */
  290.  
  291.        /* store address of BSS object 
  292.           in stack frame.
  293.        */
  294.        gen("pea",structname,"  ");
  295.        gen("move.l","(sp)+",addrbuf); 
  296.       }
  297.      }     
  298.     }
  299.     insymbol();
  300.    }
  301.    while (sym == comma);  
  302.   }
  303.  } 
  304. }
  305.  
  306. void define_constant()
  307. {
  308. /* define a NUMERIC constant 
  309.    syntax: CONST <ident>=[-|+]<numconst>[,..] 
  310. */
  311. char  const_id[MAXIDSIZE];
  312. BOOL  numconstant;
  313. int   consttyp;
  314. SHORT shortc;
  315. LONG  longc;
  316. float singlec;
  317. BOOL  negate;
  318. int   oldlevel;
  319.  
  320.  /* define all constants 
  321.     at level ZERO */
  322.  oldlevel=lev;
  323.  lev=ZERO;
  324.  
  325.  do
  326.  {
  327.   numconstant=FALSE;
  328.   negate=FALSE;
  329.  
  330.   insymbol();
  331.   if (sym != ident)
  332.      _error(7);
  333.   else
  334.   {
  335.    strcpy(const_id,id); /* save name */
  336.    insymbol();
  337.    if (sym != equal)
  338.       _error(5);
  339.    else
  340.    {
  341.     insymbol();
  342.     if (exist(const_id,constant)) /* don't try to reassign it! */
  343.        _error(53);
  344.     else
  345.     {
  346.      /* unary minus or plus? (optional) */
  347.      if ((sym == minus) || (sym == plus))
  348.      { 
  349.       switch(sym)
  350.       {
  351.        case minus : negate=TRUE;  break;
  352.        case plus  : negate=FALSE; break;
  353.       }
  354.       insymbol();
  355.      }
  356.  
  357.      /* literal constant? */
  358.      if ((sym == shortconst) || (sym == longconst) || (sym == singleconst))
  359.      { 
  360.       numconstant=TRUE; 
  361.       consttyp=typ; 
  362.       switch(consttyp)
  363.       {
  364.        case shorttype  : shortc=shortval; break;
  365.        case longtype   : longc=longval; break;
  366.        case singletype : singlec=singleval; break;
  367.       }
  368.      }
  369.      else
  370.      /* defined constant? */
  371.      if ((sym == ident) && (exist(id,constant))) 
  372.      {
  373.       consttyp=curr_item->type;
  374.       if (consttyp != stringtype) 
  375.       {
  376.        numconstant=TRUE;
  377.        switch(consttyp)
  378.        {
  379.         case shorttype  : shortc=curr_item->numconst.shortnum;   break;
  380.         case longtype   : longc=curr_item->numconst.longnum;     break;
  381.         case singletype : singlec=curr_item->numconst.singlenum; break;
  382.        }
  383.       }
  384.       else _error(27);
  385.      }  
  386.      else _error(27);
  387.     }
  388.  
  389.     /* create a new numeric constant? */
  390.     if (numconstant)
  391.     {          
  392.      switch(consttyp) 
  393.      {
  394.       case shorttype   : enter(const_id,shorttype,constant,0); 
  395.              if (negate) shortc *= -1;
  396.                   curr_item->numconst.shortnum=shortc;
  397.                  break;
  398.  
  399.       case longtype    : enter(const_id,longtype,constant,0);
  400.              if (negate) longc *= -1;
  401.                         curr_item->numconst.longnum=longc;
  402.                  break;
  403.  
  404.       case singletype  : enter(const_id,singletype,constant,0);
  405.              if (negate) singlec = SPMul(singlec,-1.0);
  406.                  curr_item->numconst.singlenum=singlec;
  407.                  break;
  408.      }
  409.      insymbol();
  410.     }
  411.    }
  412.   }
  413.  }
  414.  while (sym == comma);
  415.  
  416.  /* restore level */
  417.  lev=oldlevel;
  418. }
  419.  
  420. void declare_variable(vartype)
  421. int vartype;
  422. {
  423. /* declare a variable 
  424.    and initialise it. 
  425. */
  426. char addrbuf[40];
  427. LONG string_size=MAXSTRLEN;
  428. BOOL normal_string_variable=TRUE;
  429. SYM  *str_item;
  430.  
  431.  do
  432.  {
  433.   insymbol();
  434.   if (sym != ident) _error(7);
  435.   else
  436.   {
  437.    if (exist(id,variable)) { _error(54); insymbol(); }
  438.    else
  439.    {
  440.     enter(id,vartype,variable,0);
  441.  
  442.     itoa(-1*curr_item->address,addrbuf,10);
  443.     strcat(addrbuf,frame_ptr[lev]);
  444.     
  445.     insymbol();
  446.  
  447.     switch(vartype)
  448.     {
  449.      case shorttype  :  gen("move.w","#0",addrbuf); break;
  450.  
  451.      case longtype   :  gen("move.l","#0",addrbuf); break;
  452.  
  453.      case singletype :  gen("move.l","#0",addrbuf); break; 
  454.  
  455.      case stringtype :  str_item = curr_item;
  456.             if (sym == addresssym)
  457.             {
  458.              normal_string_variable=FALSE;
  459.              /* don't want to create a BSS object! */
  460.              str_item->new_string_var=FALSE; 
  461.  
  462.                insymbol();
  463.              if (expr() != longtype)
  464.                     _error(4);
  465.                   else
  466.                       /* store address of string in stack frame */
  467.                       gen("move.l","(sp)+",addrbuf);        
  468.             }
  469.             else
  470.             if (sym == sizesym)
  471.             {
  472.              insymbol();
  473.              if (sym == shortconst) string_size=(LONG)shortval;
  474.              else
  475.              if (sym == longconst) string_size=longval;
  476.              else 
  477.              if (sym == ident && exist(id,constant))
  478.              {
  479.               if (curr_item->type == shorttype)
  480.                  string_size=(LONG)curr_item->numconst.shortnum;
  481.               else    
  482.               if (curr_item->type == longtype)
  483.                  string_size=curr_item->numconst.longnum;
  484.               else
  485.                   _error(4);
  486.              }
  487.              else
  488.              if (sym == singleconst) 
  489.                  _error(4);
  490.              else
  491.                  _error(27); /* numeric constant expected */
  492.  
  493.              if (string_size <= 0L) _error(41); /* not positive! */
  494.  
  495.              insymbol();
  496.             }
  497.             
  498.             if (normal_string_variable)
  499.             {
  500.              /* initialise with the NULL string */
  501.              enter_DATA("_nullstring:","dc.b 0");
  502.              gen("pea","_nullstring","  ");
  503.              assign_to_string_variable(str_item,string_size);
  504.             }
  505.             
  506.             str_item->decl=declared;
  507.             str_item->size=string_size; 
  508.  
  509.             break;       
  510.     }
  511.    }
  512.   }
  513.  }
  514.  while (sym == comma); 
  515. }
  516.  
  517. void define_external_object()
  518. {
  519.  /* declare an external 
  520.     function or variable 
  521.  */
  522.  
  523.  insymbol();
  524.  if (sym  == functionsym) 
  525.     define_external_function();
  526.  else
  527.     define_external_variable();
  528. }
  529.   
  530. void define_external_variable()
  531. {
  532. /* declare an external variable */
  533. char buf[MAXIDSIZE],extvarid[MAXIDSIZE+1];
  534. int  oldlevel;
  535. int  vartype=undefined;
  536.  
  537.  /* all external variables are at level ZERO */
  538.  oldlevel=lev;
  539.  lev=ZERO;
  540.  
  541.  /* type identifiers */
  542.  if (sym == shortintsym || sym == longintsym || sym == addresssym ||
  543.      sym == singlesym || sym == stringsym)
  544.  {
  545.    switch(sym)
  546.    {
  547.     case shortintsym : vartype = shorttype;  break;
  548.     case longintsym  : vartype = longtype;   break;
  549.     case addresssym  : vartype = longtype;   break;
  550.     case singlesym   : vartype = singletype; break;
  551.     case stringsym   : vartype = stringtype; break;
  552.    }
  553.    insymbol();
  554.  }
  555.  
  556.  /* get the variable's name */
  557.  if (sym != ident)
  558.      _error(7);
  559.  {
  560.      /* 
  561.     ** Add an underscore prefix 
  562.        ** if one is not present.
  563.     */
  564.     strcpy(buf,ut_id);
  565.     remove_qualifier(buf);
  566.     if (buf[0] != '_')
  567.     {
  568.            strcpy(extvarid,"_\0");
  569.            strcat(extvarid,buf);
  570.       }
  571.       else 
  572.               strcpy(extvarid,buf);
  573.  
  574.       /* enter variable into symbol table */
  575.      if (vartype == undefined) vartype = typ;
  576.       if (exist(extvarid,extvar))
  577.         _error(54);    /* variable exists */
  578.     else
  579.     {
  580.           enter(extvarid,vartype,extvar,0);
  581.  
  582.           /* make an external reference to it */
  583.           enter_XREF(extvarid);
  584.     }
  585.  
  586.       insymbol();
  587.  } 
  588.  
  589.  lev=oldlevel;
  590. }
  591.  
  592. void define_external_function()
  593. {
  594. /* declare an external function */
  595. char buf[MAXIDSIZE],extfuncid[MAXIDSIZE+1];
  596. int  oldlevel;
  597. int  functype=undefined;
  598.  
  599.  /* all external functions are at level ZERO */
  600.  oldlevel=lev;
  601.  lev=ZERO; 
  602.  
  603.  insymbol();
  604.  
  605.  /* type identifiers */
  606.  if (sym == shortintsym || sym == longintsym || sym == addresssym ||
  607.      sym == singlesym || sym == stringsym)
  608.  {
  609.    switch(sym)
  610.    {
  611.     case shortintsym : functype = shorttype;  break;
  612.     case longintsym  : functype = longtype;   break;
  613.     case addresssym  : functype = longtype;   break;
  614.     case singlesym   : functype = singletype; break;
  615.     case stringsym   : functype = stringtype; break;
  616.    }
  617.    insymbol();
  618.  }
  619.  
  620.  /* get the function's name */
  621.  if (sym != ident)
  622.     _error(7);
  623.  {
  624.   /* add an underscore prefix 
  625.      if one is not present 
  626.   */
  627.   strcpy(buf,ut_id);
  628.   remove_qualifier(buf);
  629.   if (buf[0] != '_')
  630.   {
  631.    strcpy(extfuncid,"_\0");
  632.    strcat(extfuncid,buf);
  633.   }
  634.   else 
  635.       strcpy(extfuncid,buf);
  636.   
  637.   /* enter function into symbol table */
  638.   if (functype == undefined) functype = typ; 
  639.   if (exist(extfuncid,extfunc))
  640.     _error(33);    /* duplicate function name */
  641.   else
  642.   {
  643.       enter(extfuncid,functype,extfunc,0);
  644.   
  645.       /* make an external reference to it */
  646.       enter_XREF(extfuncid);
  647.   }
  648.  
  649.   insymbol();
  650.  } 
  651.  
  652.  lev=oldlevel;
  653. }
  654.  
  655. void call_external_function(extfuncid,need_symbol)
  656. char *extfuncid;
  657. BOOL *need_symbol;
  658. {
  659. /* CALL an external function -- level ZERO */
  660. SYM   *extfunc_item;
  661. int   i;
  662. SHORT popcount=0;
  663. char  buf[40],numbuf[40];
  664.  
  665.   if (exist(extfuncid,extfunc)) /* preserve case */
  666.   {
  667.    /* save registers */
  668.    gen("movem.l","d1-d7/a0-a6","-(sp)");
  669.  
  670.    extfunc_item=curr_item;
  671.    /* insymbol() is called before entry to this function */
  672.    if (sym == lparen) { load_mc_params(extfunc_item); *need_symbol=TRUE; } 
  673.    else
  674.       { extfunc_item->no_of_params=0; *need_symbol=FALSE; }
  675.  
  676.      /* call routine */
  677.      gen("jsr",extfunc_item->name,"  ");
  678.  
  679.      /* pop parameters? */
  680.      if (extfunc_item->no_of_params != 0)
  681.      {
  682.       popcount=0;
  683.       for (i=0;i<extfunc_item->no_of_params;i++) 
  684.       {
  685.        if (extfunc_item->p_type[i] == shorttype) 
  686.            popcount += 2;
  687.        else
  688.        popcount += 4;
  689.       }
  690.       /* add popcount to sp */
  691.       strcpy(buf,"#\0");
  692.       itoa(popcount,numbuf,10);
  693.       strcat(buf,numbuf);
  694.       gen("add.l",buf,"sp");
  695.      }
  696.  
  697.      /* restore registers */
  698.      gen("movem.l","(sp)+","d1-d7/a0-a6"); 
  699.   }
  700. }
  701.  
  702. void define_common_or_global_variable(varsym)
  703. int varsym;
  704. {
  705. /*
  706. ** Declare a common or global variable.
  707. ** Treated internally as an external variable.
  708. */
  709. char buf[MAXIDSIZE];
  710. char extvarid[MAXIDSIZE+2],extvarlabel[MAXIDSIZE+3];
  711. int  oldlevel;
  712. int  vartype=undefined;
  713. SYM  *str_item;
  714. LONG string_size = MAXSTRLEN;
  715. BOOL normal_string_variable = TRUE;
  716. char bss_size[20];
  717.  
  718.  insymbol();
  719.  
  720.  /* all common variables are at level ZERO */
  721.  oldlevel=lev;
  722.  lev=ZERO;
  723.  
  724.  /* optional type identifiers */
  725.  if (sym == shortintsym || sym == longintsym || sym == addresssym ||
  726.      sym == singlesym || sym == stringsym)
  727.  {
  728.    switch(sym)
  729.    {
  730.     case shortintsym : vartype = shorttype;  break;
  731.     case longintsym  : vartype = longtype;   break;
  732.     case addresssym  : vartype = longtype;   break;
  733.     case singlesym   : vartype = singletype; break;
  734.     case stringsym   : vartype = stringtype; break;
  735.    }
  736.  
  737.    insymbol();
  738.  }
  739.  
  740.  /* get the variable's name */
  741.  if (sym != ident)
  742.      _error(7);
  743.  {
  744.      /* 
  745.     ** Add an underscore prefix 
  746.        ** if one is not present.
  747.     */
  748.     strcpy(buf,ut_id);
  749.     remove_qualifier(buf);
  750.     if (buf[0] != '_')
  751.     {
  752.         sprintf(extvarid,"_%s",buf);
  753.       }
  754.       else 
  755.               strcpy(extvarid,buf);
  756.     
  757.       /* enter variable into symbol table */
  758.      if (vartype == undefined) vartype = typ;
  759.       if (exist(extvarid,extvar))
  760.         _error(54);    /* variable exists  */
  761.     else
  762.     {
  763.         enter(extvarid,vartype,extvar,0);
  764.         
  765.         /* 
  766.         ** Make an appropriate BSS object.
  767.         */
  768.         sprintf(extvarlabel,"%s:",extvarid);
  769.         switch(vartype)
  770.         {
  771.             case shorttype:     enter_BSS(extvarlabel,"ds.w 1"); 
  772.                      gen("move.w","#0",extvarid);
  773.                      insymbol(); break;
  774.  
  775.             case longtype:      enter_BSS(extvarlabel,"ds.l 1");
  776.                      gen("move.l","#0",extvarid); 
  777.                      insymbol(); break;
  778.  
  779.             case singletype: enter_BSS(extvarlabel,"ds.l 1"); 
  780.                      gen("move.l","#0",extvarid); 
  781.                      insymbol(); break;
  782.  
  783.             case stringtype: insymbol();
  784.                       if (sym == sizesym)
  785.                      { 
  786.                          insymbol();
  787.  
  788.                         /* create own BSS object */
  789.                          str_item->new_string_var = FALSE; 
  790.  
  791.                          if (sym == shortconst) string_size=(LONG)shortval;
  792.                          else
  793.                          if (sym == longconst) string_size=longval;
  794.                          else 
  795.                          if (sym == ident && exist(id,constant))
  796.                          {
  797.                               if (curr_item->type == shorttype)
  798.                                    string_size=(LONG)curr_item->numconst.shortnum;
  799.                               else    
  800.                               if (curr_item->type == longtype)
  801.                                    string_size=curr_item->numconst.longnum;
  802.                               else
  803.                                     _error(4);
  804.                           }
  805.                           else
  806.                           if (sym == singleconst) 
  807.                                  _error(4);
  808.                           else
  809.                                  _error(27); /* numeric constant expected */
  810.  
  811.                           if (string_size <= 0L) _error(41); /* not positive! */
  812.  
  813.                           insymbol();
  814.                      }
  815.             
  816.                     str_item->decl=declared;
  817.                     str_item->size=string_size; 
  818.  
  819.                     /*
  820.                     ** Create BSS object.
  821.                     */
  822.                     sprintf(bss_size,"ds.l %d",string_size);
  823.                     enter_BSS(extvarlabel,bss_size);
  824.  
  825.                      if (normal_string_variable)
  826.                      {
  827.                          /* initialise with the NULL string */
  828.                          enter_DATA("_nullstring:","dc.b 0");
  829.                          gen("lea",extvarid,"a0");
  830.                          gen("lea","_nullstring","a1");
  831.                          gen("jsr","_strcpy","  ");
  832.                         enter_XREF("_strcpy");
  833.                      }
  834.             
  835.                     break;       
  836.         }
  837.  
  838.         /*
  839.         ** Only make it externally referenceable if it's a COMMON variable
  840.         ** not a GLOBAL variable.
  841.         */
  842.         if (varsym == commonsym)
  843.         {
  844.               /* 
  845.             ** Make it externally referenceable.
  846.             ** The '*' is used by enter_XREF() 
  847.             ** to make this an XDEF.
  848.             */
  849.             extvarid[0] = '*';
  850.               enter_XREF(extvarid);
  851.         }
  852.     }
  853.  } 
  854.  
  855.  lev=oldlevel;
  856. }
  857.